package com.rockcent.mall.controller;

import com.rockcent.common.common.JsonResult;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.RestDoing;
import com.rockcent.common.controller.BaseController;
import com.rockcent.common.utils.DateFormatUtils;
import com.rockcent.common.utils.DateUtils;
import com.rockcent.mall.Routes;
import com.rockcent.mall.helper.UserHelper;
import com.rockcent.mall.lib.domain.enumclass.StatististicsType;
import com.rockcent.mall.lib.dto.MerchantCustomerStatisticsDto;
import com.rockcent.mall.lib.dto.UserInfoDto;
import com.rockcent.mall.lib.repository.OrderEventRepository;
import com.rockcent.mall.lib.repository.ProductEventRepository;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by Marco on 16-12-13.
 * 客户统计
 */
@RestController
public class MerchantCustomerStatisticsController extends BaseController {

    private final Logger log = LoggerFactory.getLogger(MerchantCustomerStatisticsController.class);

    @Autowired
    private UserHelper userHelper;

    @Autowired
    private ProductEventRepository productEventRepository;

    @Autowired
    private OrderEventRepository orderEventRepository;

    /**
     * @api {get}/merchant/customer/statistics/info 客户统计
     * @apiGroup B端 merchant customer statistics
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String} searchDateType YESTERDAY("昨天"), WEEK("最近一周"), MONTH("最近一个月"), QUATER("最近三个月")
     * @apiParam {String} startDate 开始时间
     * @apiParam {String} endDate 结束时间
     *
     * @apiSuccess {Long} customerNum 总购买客户数
     * @apiSuccess {Long} unpayCustomerNum 未支付客户
     * @apiSuccess {Long} payNewCustomerNum 支付新客户
     * @apiSuccess {Long} payOldCustomerNum 支付旧客户
     *
     * @apiSuccess {Long} sourceCustomerNum 客户来源－客户数
     * @apiSuccess {String} sourceCustomerDate 客户来源－日期
     *
     * @apiSuccess {List} pageResult 活跃用户列表
     * @apiSuccess {String} customerName 活跃客户－客户名称
     * @apiSuccess {String} mobile 活跃客户－联系电话
     * @apiSuccess {Long} orderNum 活跃客户－累计订单数
     * @apiSuccess {Long} buyNum 活跃客户－购买产品数
     * @apiSuccess {Long} returnNum 活跃客户－已退产品数
     * @apiSuccess {Long} totalAmount 活跃客户－累计消费额
     * @apiSuccess {Long} perPrice 活跃客户－客单价
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *   "code": "1",
     *   "desc": "成功",
     *   "data": {
     *     "customerNum": 1,
     *     "unpayCustomerNum": 1,
     *     "payNewCustomerNum": 0,
     *     "payOldCustomerNum": 1,
     *     "sourceCustomerStatisticsList": [
     *       {
     *         "sourceCustomerNum": 84,
     *         "sourceType": "wechat",
     *         "sourceCustomerDate": "2016.12.08"
     *       },
     *       {
     *         "sourceCustomerNum": 66,
     *         "sourceType": "wechat",
     *         "sourceCustomerDate": "2016.12.09"
     *       }
     *     ],
     *     ......
     *   }
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_CUSTOMER_STATISTICS_INFO, method = RequestMethod.GET)
    public JsonResult info(MerchantCustomerStatisticsDto merchantCustomerStatisticsDto, HttpServletRequest request) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            String searchDateType = merchantCustomerStatisticsDto.getSearchDateType();
            String startDate = merchantCustomerStatisticsDto.getStartDate();
            String endDate = merchantCustomerStatisticsDto.getEndDate();
            boolean isCheckType = true;
            boolean isCheckDate = true;
            if(StringUtils.isEmpty(searchDateType)) {
                isCheckType = false;
            }
            if(StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) {
                isCheckDate = false;
            }
            if(!isCheckType && !isCheckDate) {
                jsonResult.remind("查询条件不能全为空",log);
                return;
            }
            if (StringUtils.isNotBlank(searchDateType) && !EnumUtils.isValidEnum(StatististicsType.class, searchDateType)) {
                jsonResult.remind("searchDateType 必须为 YESTERDAY(\"昨天\"), WEEK(\"最近一周\"), MONTH(\"最近一个月\"), QUATER(\"最近三个月\")",log);
                return;
            }
            if (StringUtils.isNotBlank(searchDateType)) {
                //昨天
                if (StatististicsType.YESTERDAY == StatististicsType.valueOf(searchDateType)) {
                    Date today = DateUtils.getCurrentDate(DateFormatUtils.DATE_FORMAT1);
                    startDate = DateUtils.addDayToDate(-1,today,DateFormatUtils.DATE_FORMAT1);
                    endDate = DateUtils.addDayToDate(-1,today,DateFormatUtils.DATE_FORMAT1);
                }
                //每周
                if (StatististicsType.WEEK == StatististicsType.valueOf(searchDateType)) {
                    Date today = DateUtils.getCurrentDate(DateFormatUtils.DATE_FORMAT1);
                    startDate = DateUtils.addDayToDate(-6,today,DateFormatUtils.DATE_FORMAT1);
                    endDate = DateUtils.getCurrentTime(DateFormatUtils.DATE_FORMAT1);
                }
                //近一个月
                if (StatististicsType.MONTH == StatististicsType.valueOf(searchDateType)) {
                    Date today = DateUtils.getCurrentDate(DateFormatUtils.DATE_FORMAT1);
                    startDate = DateUtils.addMothToDate(-1,today,DateFormatUtils.DATE_FORMAT1);
                    endDate = DateUtils.getCurrentTime(DateFormatUtils.DATE_FORMAT1);
                }
                //近三个月
                if (StatististicsType.QUATER == StatististicsType.valueOf(searchDateType)) {
                    Date today = DateUtils.getCurrentDate(DateFormatUtils.DATE_FORMAT1);
                    startDate = DateUtils.addMothToDate(-3,today,DateFormatUtils.DATE_FORMAT1);
                    endDate = DateUtils.getCurrentTime(DateFormatUtils.DATE_FORMAT1);
                }
            }
            List<MerchantCustomerStatisticsDto> customerList = null;
            if(StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
                int days = DateUtils.compareDate(startDate,endDate,0);
                if(days==0) {
                    merchantCustomerStatisticsDto.setGroupByType("hour");
                } else if(days>0 && days<=31) {
                    merchantCustomerStatisticsDto.setGroupByType("day");
                } else if(days > 31) {
                    merchantCustomerStatisticsDto.setGroupByType("month");
                }
                customerList = initData(merchantCustomerStatisticsDto,days,startDate,endDate);
            }
            if(StringUtils.isNotBlank(startDate)) {
                merchantCustomerStatisticsDto.setStartDate(startDate+" 00:00:00");
            }
            if(StringUtils.isNotBlank(endDate)) {
                merchantCustomerStatisticsDto.setEndDate(endDate+" 23:59:59");
            }
            MerchantCustomerStatisticsDto statisticsDto = new MerchantCustomerStatisticsDto();
            statisticsDto.setCustomerNum(0L);
            //总购买客户数
            Long customerNum = orderEventRepository.findBuyerIdNumByMerchantIdAndDate(userInfoDto.mall.getId(), userInfoDto.merchant.getId(),merchantCustomerStatisticsDto.getStartDate(),merchantCustomerStatisticsDto.getEndDate());
            if(customerNum!=null) {
                statisticsDto.setCustomerNum(customerNum);
            }
            //未支付客户
            statisticsDto.setUnpayCustomerNum(0L);
            Long unpayCustomerNum = orderEventRepository.findUnpayCustomerNumByMerchantIdAndDate(userInfoDto.mall.getId(),userInfoDto.merchant.getId(),merchantCustomerStatisticsDto.getStartDate(),merchantCustomerStatisticsDto.getEndDate());
            if(unpayCustomerNum!=null) {
                statisticsDto.setUnpayCustomerNum(unpayCustomerNum);
            }
            //支付新客户
            statisticsDto.setPayNewCustomerNum(0L);
            Long payNewCustomerNum = orderEventRepository.findPayNewCustomerNumByMerchantIdAndDate(userInfoDto.mall.getId(), userInfoDto.merchant.getId(),merchantCustomerStatisticsDto.getStartDate(),merchantCustomerStatisticsDto.getEndDate());
            if(payNewCustomerNum!=null) {
                statisticsDto.setPayNewCustomerNum(payNewCustomerNum);
            }
            //支付旧客户
            statisticsDto.setPayOldCustomerNum(0L);
            Long payOldCustomerNum = orderEventRepository.findPayOldCustomerNumByMerchantIdAndDate(userInfoDto.mall.getId(), userInfoDto.merchant.getId(),merchantCustomerStatisticsDto.getStartDate(),merchantCustomerStatisticsDto.getEndDate());
            if(payOldCustomerNum!=null) {
                statisticsDto.setPayOldCustomerNum(payOldCustomerNum);
            }
            //客户来源列表
            List<MerchantCustomerStatisticsDto> sourceCustomerStatisticsList = productEventRepository.findCustomersByMerchantIdandDate(userInfoDto.mall.getId(), userInfoDto.merchant.getId(),merchantCustomerStatisticsDto.getStartDate(),merchantCustomerStatisticsDto.getEndDate(),merchantCustomerStatisticsDto.getGroupByType());
            changeCustomerStatistcs(customerList,sourceCustomerStatisticsList);
            statisticsDto.setSourceCustomerStatisticsList(customerList);
            //活跃客户
            statisticsDto.setActiveCustomerList(new ArrayList<>());
            PageResult<MerchantCustomerStatisticsDto> pageResult = orderEventRepository.findActiveCustomerListByMerchantIdandDate(userInfoDto.mall.getId(), userInfoDto.merchant.getId(),merchantCustomerStatisticsDto.getStartDate(),merchantCustomerStatisticsDto.getEndDate(),
                    this.getPage(merchantCustomerStatisticsDto.getPageNo(), merchantCustomerStatisticsDto.getPageSize()));
            if(pageResult!=null && pageResult.data!=null && pageResult.data.size()>0) {
                for(MerchantCustomerStatisticsDto dto : pageResult.data) {
                    dto.setReturnNum(0L);
                    dto.setPerPrice(BigDecimal.valueOf(0));
                    if(dto.getCustomerId()==null) {
                        continue;
                    }
                    //取消订单总数量
                    Long cancelOrderNum = orderEventRepository.findCancelOrderNumByMerchantIdandDate(userInfoDto.mall.getId(), userInfoDto.merchant.getId(),merchantCustomerStatisticsDto.getStartDate(),merchantCustomerStatisticsDto.getEndDate(),dto.getCustomerId());
                    if(cancelOrderNum!=null) {
                        dto.setReturnNum(cancelOrderNum);
                    }
                    if(dto.getOrderNum()!=null && dto.getOrderNum()>0) {
                        //订单总金额/订单总数=客单价
                        BigDecimal amount = dto.getTotalAmount()==null?BigDecimal.valueOf(0):dto.getTotalAmount();
                        BigDecimal orderNum = new BigDecimal(dto.getOrderNum());
                        dto.setPerPrice(amount.divide(orderNum,2,BigDecimal.ROUND_HALF_UP));
                    }

                }
            }
            statisticsDto.setPageResult(pageResult);
            jsonResult.data = statisticsDto;
        };
        return doing.go(request, log);
    }

    /**
     * 将数据查询出来的数据更新到初始化列表
     * @param initDataList
     * @param customerList
     * @throws Exception
     */
    private void changeCustomerStatistcs(List<MerchantCustomerStatisticsDto> initDataList, List<MerchantCustomerStatisticsDto> customerList) throws Exception {
        if(customerList==null || customerList.size()==0 || initDataList==null || initDataList.size()==0) {
            return;
        }
        for(MerchantCustomerStatisticsDto dto : initDataList) {
            MerchantCustomerStatisticsDto customerStatisticsDto = selectDTO(customerList,dto.getSourceCustomerDate());
            if(customerStatisticsDto!=null && customerStatisticsDto.getSourceCustomerNum()!=null) {
                dto.setSourceCustomerNum(customerStatisticsDto.getSourceCustomerNum());
            }
        }
    }

    /**
     * 通过时间查找对应的记录
     * @return
     * @throws Exception
     */
    private MerchantCustomerStatisticsDto selectDTO(List<MerchantCustomerStatisticsDto> customerList, String date) throws Exception {
        MerchantCustomerStatisticsDto dto = null;
        if(customerList!=null && customerList.size()>0) {
            for(MerchantCustomerStatisticsDto customerStatisticsDto : customerList) {
                if(customerStatisticsDto.getSourceCustomerDate().equals(date)) {
                    return customerStatisticsDto;
                }
            }
        }
        return dto;
    }

    /**
     * 初始化月日小时数据
     * @throws Exception
     */
    private List<MerchantCustomerStatisticsDto> initData(MerchantCustomerStatisticsDto dto, int days, String startDate, String endDate) throws Exception {
        List<MerchantCustomerStatisticsDto> list = new ArrayList<>();
        if(days>=0 && StringUtils.isNotEmpty(startDate)) {
            if(dto.getGroupByType().equals("hour")) {
                for(int i = 0; i < 24; i++) {
                    String hour = i>9?String.valueOf(i):"0"+i;
                    list.add(initMerchantCustomerStatisticsDto(hour));
                }
            } else if(dto.getGroupByType().equals("day")) {
                for (int i = 0; i <= days; i++) {
                    String date = DateUtils.addDayToDate(i,startDate,DateFormatUtils.DATE_FORMAT1).replace("-",".");
                    list.add(initMerchantCustomerStatisticsDto(date));
                }
            } else if(dto.getGroupByType().equals("month")) {
                int monthNum = DateUtils.compareDate(startDate,endDate,1)+1;
                for (int i = 0; i < monthNum; i++) {
                    String currentMonth = DateUtils.addMothToDate(i,startDate,DateFormatUtils.DATE_FORMAT1);
                    String yearMonth = currentMonth.replace("-",".").substring(0,7);
                    list.add(initMerchantCustomerStatisticsDto(yearMonth));
                }
            } else if(dto.getGroupByType().equals("year")) {
                int startYear = DateUtils.getCurrentYear(startDate);
                int endYear = DateUtils.getCurrentYear(endDate);
                for(;startYear<=endYear;startYear++) {
                    list.add(initMerchantCustomerStatisticsDto(String.valueOf(startYear)));
                }
            }
        }
        return list;
    }

    /**
     * 初始化MerchantCustomerStatisticsDto数据
     * @param date
     * @return
     * @throws Exception
     */
    private MerchantCustomerStatisticsDto initMerchantCustomerStatisticsDto(String date) throws Exception {
        MerchantCustomerStatisticsDto statisticsDto = new MerchantCustomerStatisticsDto();
        statisticsDto.setSourceType("wechat");
        statisticsDto.setSourceCustomerNum(0L);
        statisticsDto.setSourceCustomerDate(date);
        return statisticsDto;
    }

}
